package org.ourgrid.common.statistics.control;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.ourgrid.common.interfaces.to.LocalWorkerState;
import org.ourgrid.common.internal.IResponseTO;
import org.ourgrid.common.spec.worker.WorkerSpec;
import org.ourgrid.common.statistics.beans.peer.Worker;
import org.ourgrid.common.statistics.util.hibernate.HibernateUtil;
import org.ourgrid.peer.business.dao.PeerDAOFactory;
import org.ourgrid.peer.business.dao.statistics.WorkerDAO;
import org.ourgrid.peer.business.util.LoggerUtil;
import org.ourgrid.peer.to.LocalWorker;

public class WorkerControl {
	
	private static WorkerControl instance = null;
	
	public static WorkerControl getInstance() {
		if (instance == null) {
			instance = new WorkerControl();
		}
		return instance;
	}
	
	public void statusChanged(List<IResponseTO> responses, String workerUserAtServer, LocalWorkerState workerStatus) {
		
		responses.add(LoggerUtil.enter());
		
		HibernateUtil.beginTransaction();
		
		try {
			getWorkerDAO().statusChanged(responses, workerUserAtServer, workerStatus);
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
		responses.add(LoggerUtil.leave());

	}
	
	public void statusChanged(List<IResponseTO> responses, String workerUserAtServer, LocalWorkerState workerStatus, String allocatedFor) {
		
		responses.add(LoggerUtil.enter());
		
		HibernateUtil.beginTransaction();
		
		try {
			getWorkerDAO().statusChanged(responses, workerUserAtServer, workerStatus, allocatedFor);
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
		responses.add(LoggerUtil.leave());

	}
	
	public void addLocalWorker(List<IResponseTO> responses, LocalWorker localWorker, String myUserAtServer) {
		responses.add(LoggerUtil.enter());
		
		HibernateUtil.beginTransaction();
		
		try {
			getWorkerDAO().addLocalWorker(responses, localWorker, myUserAtServer);
			
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}

		responses.add(LoggerUtil.leave());
	}
	
	public void addRemoteWorker(List<IResponseTO> responses, WorkerSpec workerSpec, String providerDN, String consumerUserAtServer) {
		responses.add(LoggerUtil.enter());
		
		HibernateUtil.beginTransaction();
		
		try {
			getWorkerDAO().addRemoteWorker(responses, workerSpec, providerDN, consumerUserAtServer);
			
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}

		responses.add(LoggerUtil.leave());
	}
	

	public void updateWorker(List<IResponseTO> responses, String workerUserAtServer, Map<String, String> currentAttributes, Map<String, String> currentAnnotations) {
		responses.add(LoggerUtil.enter());
		
		HibernateUtil.beginTransaction();
		
		try {
			getWorkerDAO().updateWorker(responses, workerUserAtServer, currentAttributes, currentAnnotations);
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
		responses.add(LoggerUtil.leave());
	}
	
	public LocalWorker getLocalWorker(List<IResponseTO> responses, String workerUserAtServer) {
		HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		LocalWorker worker = PeerDAOFactory.getInstance().getLocalWorkersDAO().getLocalWorker(responses, workerUserAtServer);
		
		HibernateUtil.closeSession();

		return worker;
	}
	
	public Collection<LocalWorker> getLocalWorkers(List<IResponseTO> responses, 
			String peerUserAtServer,LocalWorkerState status) {
		HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		Collection<LocalWorker> workers = PeerDAOFactory.getInstance().getLocalWorkersDAO().
		getLocalWorkers(responses, peerUserAtServer, status);
		HibernateUtil.closeSession();

		return workers;
	}
	
	public boolean isNewWorker(List<IResponseTO> responses, String workerAtServer) {
		HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		boolean isNew = PeerDAOFactory.getInstance().getLocalWorkersDAO().isNewWorker(responses, workerAtServer);
		HibernateUtil.closeSession();

		return isNew;
	}
	
	public Collection<String> getLocalWorkersUserAtServer(List<IResponseTO> responses, String myUserAtServer) {
		HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		Collection<String> localWorkersAddress = PeerDAOFactory.getInstance().getLocalWorkersDAO().getLocalWorkersUserAtServer(responses, myUserAtServer);
		
		HibernateUtil.closeSession();

		return localWorkersAddress;
	}
	
	public LocalWorker removeLocalWorker(List<IResponseTO> responses, String localWorkerUserAtServer) {
		
		responses.add(LoggerUtil.enter());
		
		HibernateUtil.beginTransaction();
		
		LocalWorker localWorker = null;
		
		try {
			localWorker = PeerDAOFactory.getInstance().getWorkerDAO().removeLocalWorker(responses, 
					localWorkerUserAtServer);
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
		responses.add(LoggerUtil.leave());
		return localWorker;
	}
	
	public void removeRemoteWorker(List<IResponseTO> responses, String remoteWorkerUserAtServer) {
		
		responses.add(LoggerUtil.enter());
		
		HibernateUtil.beginTransaction();
		
		try {
			getWorkerDAO().removeRemoteWorker(responses, remoteWorkerUserAtServer);
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
		responses.add(LoggerUtil.leave());
	}
	
	public Collection<Worker> findAllActiveWorkers(List<IResponseTO> responses, String myUserAtServer) {
		HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		Collection<Worker> workers = getWorkerDAO().findAllActiveWorkers(responses, myUserAtServer);
		HibernateUtil.closeSession();

		return workers;
	}
	
	public LocalWorker getRecoveredWorker(List<IResponseTO> responses, String workerUserAtServer) {
		HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		LocalWorker worker = PeerDAOFactory.getInstance().getLocalWorkersDAO().getRecoveredWorker(
				responses, workerUserAtServer);
		HibernateUtil.closeSession();

		return worker;
	}
	
	public Worker findActiveWorker(List<IResponseTO> responses, String workerUserAtServer) {
		HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		Worker worker = getWorkerDAO().findActiveWorker(responses, workerUserAtServer);
		HibernateUtil.closeSession();

		return worker;
	}
	
	public void updateWorkAccounting(List<IResponseTO> responses, String workerUserAtServer, double cpuTime, double dataStored) {
		
		HibernateUtil.beginTransaction();
		
		try {
			getWorkerDAO().updateWorkAccounting(responses, workerUserAtServer, cpuTime, dataStored);
			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		HibernateUtil.closeSession();
	}
	
	private WorkerDAO getWorkerDAO() {
		return PeerDAOFactory.getInstance().getWorkerDAO();
	}

}
